<?php
/**
 * 
 * A Wiki application
 * 
 * @category Abovo
 * 
 * @package Abovo_App_System
 * 
 * @subpackage Abovo_App_System_Wiki
 * 
 * @author Antti Holvikari <anttih@gmail.com>
 * 
 * @license http://opensource.org/licenses/gpl-license.php GPL
 * 
 */
 
/**
 * 
 * A Wiki application
 * 
 * Page names are stored lowercase in the database, but all
 * the hrefs are normalized to the format `Solar_Markdown_Wiki_Link`
 * uses.
 * 
 * @category Abovo
 * 
 * @package Abovo_App_System
 * 
 * @subpackage Abovo_App_System_Wiki
 * 
 */
class Abovo_App_Crm_Wiki extends Abovo_App_Crm {
    
    /**
     * 
     * undocumented class variable
     * 
     * @var string
     * 
     */
    public $_Abovo_App_Crm_Wiki = array(
        'read_href' => 'crm/wiki/page/%s',
    );
    
    /**
     * 
     * Form object
     * 
     * @var Solar_Form
     * 
     */
    public $form;
    
    /**
     * 
     * Markdown tips
     * 
     * @var string
     * 
     */
    public $tips;
    
    /**
     * 
     * Wiki page object
     * 
     * @var Solar_Sql_Row
     * 
     */
    public $wiki;
    
    /**
     * 
     * Wiki page name
     * 
     * @var string
     * 
     */
    public $page_name;
    
    /**
     * 
     * List of wiki pages
     * 
     * @var Solar_Sql_Rowset
     * 
     */
    public $pages;
    
    /**
     * 
     * Default action
     * 
     * @var string
     * 
     */
    protected $_action_default = 'page';
    
    /**
     * 
     * Wiki table model
     * 
     * @var Abovo_Model_Wikis
     * 
     */
    private $_wikis;
    
    /**
     * 
     * Markdown object
     * 
     * @var Solar_Markdown_Wiki
     * 
     */
    private $_markdown;
    
    /**
     * 
     * Shows one wiki page
     * 
     * @param string $page Page name
     * 
     * @return void
     * 
     */
    public function actionPage($page = 'index')
    {
        $this->wiki = $this->_wikis->fetchByName(strtolower($page));
        
        // if wiki page not found, redirect to edit page
        if (! $this->wiki) {
            return $this->_redirect("crm/wiki/edit/" . urlencode($page));
        }
        
        // normalize page name
        $this->page_name = $this->_normalizePageName($this->wiki->name);
        
        // transform Markdown to XHTML
        $this->wiki->xhtml = $this->_markdown->transform($this->wiki->body);
        
        // did we just save a page?
        $this->_msgSuccess($this->_session->getFlash('saved', null));
        
        // fetch all pages in update order
        $this->pages = $this->_wikis->fetchAll(null, 'updated DESC');
    }
    
    /**
     * 
     * Create a new wiki page
     * 
     * @param string $page Page name
     * 
     * @return void
     * 
     */
    public function actionEdit($page = 'index')
    {
        $valid = Solar::factory('Abovo_Valid');
        
        // is it a valid page name?
        if (! $valid->wikiPage($page)) {
            // no, normalize and redirect to correct page
            $this->_redirect('crm/wiki/edit/' . $this->_normalizePageName($page));
        }
        
        // from this point on, go with all lowercase
        // this will make sure it's lowercase in db
        $page = strtolower($page);
        
        $form = $this->_wikis->form();
        
        // are we saving this page?
        if ($this->_isProcess('save') && $form->validate()) {
            $data = $form->values();
            
            // fetch this wiki page
            $wiki = $this->_wikis->fetchByName($page);
            
            // did it exist?
            if (! $wiki) {
                // ...no, fetch defaults 
                $wiki = $this->_wikis->fetchNew();
            }
            
            // current user is the author
            $wiki->handle = Solar::registry('user')->auth->handle;
            
            // take page name from the URI
            $wiki->name = $page;
            // ip number
            $wiki->ip = $this->_request->server('REMOTE_ADDR');
            // wiki body
            $wiki->body = $data['wiki']['body'];
            // tags
            $wiki->tags = $data['wiki']['tags'];
            // save page
            $wiki->save();
            
            // add a flash
            $this->_session->setFlash('saved', $this->locale('SUCCESS_FORM'));
            
            // write log
            $this->_log("[{$this->user['handle']}] Saved page $page");
            
            // redirect to the page we just edited/created
            return $this->_redirect("crm/wiki/page/$page");
        }
        
        // try to find this page
        $this->wiki = $this->_wikis->fetchByName($page);
        
        // did it exist?
        if (! $this->wiki) {
            // ...no, add message
            $this->_msgSuccess($this->locale('TEXT_PAGE_NEW'));
            $this->page_name = $this->_normalizePageName($page);
        } else {
            // the page exists so implode tag names...
            $this->wiki->tags = implode(', ', $this->wiki->tags);
            
            $this->page_name = $this->_normalizePageName($this->wiki->name);
            
            // ...and populate form with all info
            $form->populate(array(
                'wiki' => $this->wiki->toArray(),
            ));
        }
        
        // assign form for view
        $this->form = $form;
        
        $this->tips = $this->locale('TEXT_MARKDOWN_TIPS');
        
        $page = $this->_normalizePageName($page);
    }
    
    /**
     * 
     * Normalizes a page name
     * 
     * @return string
     * 
     */
    protected function _normalizePageName($page)
    {
        return preg_replace('/\s+/', '_', ucfirst(trim($page)));
    }
    
    /**
     * 
     * Sets up markdown object
     * 
     * @return void
     * 
     */
    private function _setUpMarkdown()
    {
        $this->_markdown = Solar::factory('Solar_Markdown_Wiki');
        
        // get wiki link plugin and set "read href" attribute
        // from config
        $link = $this->_markdown->getPlugin('Solar_Markdown_Wiki_Link');
        
        $uri = Solar::factory('Solar_Uri_Action');
        
        // create uri with href spec
        $href = $uri->quick($this->_config['read_href']);
        
        // set the read href base
        $link->setAttrib(
            'read',
            'href',
            $href
        );
    }
    
    /**
     * 
     * Set up environment
     * 
     * @return void
     * 
     */
    protected function _setUp()
    {
        parent::_setUp();
        
        // set up markdown object
        $this->_setUpMarkdown();
        
        // set up wiki model
        $this->_wikis = Solar::factory('Abovo_Model_Wikis');
        
        // add css file
        $this->layout_head['style'][] = 'Abovo/styles/wiki.css';
        
        $this->layout_local['crm/wiki'] = $this->locale('TEXT_INDEX');
    }
}
